<?php

namespace Sharks\Core;

use InvalidArgumentException;
use Sharks\Core\Cfg\AppConfig;
use Sharks\Core\Http\Cookie;
use Sharks\Core\Http\Flash;
use Sharks\Core\Http\Request;
use Sharks\Core\Http\Response;
use Sharks\Core\Http\Session;
use Sharks\Core\LifeCycle\AppLifeCycle;
use Sharks\Core\LifeCycle\Event;
use Sharks\Core\LifeCycle\LifePiple;
use Sharks\Core\Make\Maker;
use Sharks\Core\Path\PathKit;
use Sharks\Core\Support\Bag\ParameterBag;
use Sharks\Core\Support\Base\DefValue;
use Sharks\Core\Support\Log\Log;

/**
 * 单次生命周期内应用全局数据
 *
 */
class AppContext {
	private $path;

	private $server;
	private $cookie;
	private $request;
	private $response;
	private $session;
	private $flash;
	
	/** @mode 运行模式 */
	private $mode;
	
	/** 配置文件 */
	private $config;

	private static $app = null;
	public static function instance(
		$appPath = null, 
		$mode = AppConfig::MODE_SERVER, 
		array $makes = array()) {
		
		return DefValue::isNull(self::$app, function() use ($appPath, $mode, $makes) {
			// 初始化
			self::$app = new static($appPath, $mode);
			self::$app->make($makes);
			return self::$app;
		});
	}


	/**
	 * 初始化'应用目录路径'与'运行模式'
	 * 其它初始化见 init()
	 * @param $appPath
	 * @param $mode
	 */
	public function __construct($appPath, $mode) {
		$this->path = new PathKit($appPath);
		$this->mode = $mode;
	}

	/**
	 * 初始化
	 * @throws SystemException
	 */
	protected function make(array $makers = array()) {
		if (empty($makers)) {
			//默认的初始化
			$makers = array(
				\Sharks\Core\Make\ErrorMaker::class,
				\Sharks\Core\Make\ClassLoaderMaker::class,
				\Sharks\Core\Make\AppConfigMaker::class,
				\Sharks\Core\Make\SystemSettingMaker::class,
				\Sharks\Core\Make\RouteMaker::class,
				\Sharks\Core\Make\LoggingMaker::class,
				\Sharks\Core\Make\EventMaker::class,
				\Sharks\Core\Make\AssetsMaker::class,
				\Sharks\Core\Make\DatabaseMaker::class,
			);
		}

		Maker::exec($makers, $this);
		Event::fire('app.made', $this);

		Log::debug("Maker initialized");

		$this->server = new ParameterBag($_SERVER);
		$this->cookie = new Cookie;
		$this->request = new Request($this);
		$this->response = new Response($this);
		$this->session = new Session;
		$this->flash = new Flash($this);

		Log::debug("Http Object initialized");
	}

	/**
	 * 变量
	 * @return mixed
	 */
	public function server() {
		return $this->server;
	}

	/**
	 * cookie
	 * @return mixed
	 */
	public function cookie() {
		return $this->cookie;
	}

	/**
	 * 请求
	 * @return mixed
	 */
	public function request() {
		return $this->request;
	}

	/**
	 * 响应
	 * @return mixed
	 */
	public function response() {
		return $this->response;
	}

	/**
	 * 会话
	 * @return mixed
	 */
	public function session() {
		return $this->session;
	}

	/**
	 * 运行模式
	 * @return mixed
	 */
	public function mode() {
		return $this->mode;
	}

	/**
	 * flash 访问闪存
	 * @return mixed
	 */
	public function flash() {
		return $this->flash;
	}

	/**
	 * 运行时的关键路径
	 * @return PathKit
	 */
	public function path() {
		return $this->path;
	}

	/**
	 * 运行
	 */
	public function run() {
		$life = new LifePiple($this);
		$life->line();
	}
}